import type {NextRequest} from 'next/server';
import {NextResponse} from 'next/server';
import {getRefreshToken, getUserId} from "@/lib/actions";

export const config = {
    matcher: ['/', '/admin/:path*', '/user/:path*'],
};

export async function middleware(request: NextRequest) {
    const url = request.nextUrl.clone();
    const pathname = url.pathname;

    let token = await getAccessToken(request.cookies.get('session_access_token')?.value);
    let logedIn = request.cookies.get('Iloged')?.value
    let userRole = undefined;
    if (logedIn === '1') {
        userRole = await checkUserAuth(token);
    }

    let response = NextResponse.next();

    if (!pathname.startsWith('/') && token === undefined) {
        response.cookies.delete('Iloged')
        request.cookies.delete('session_userid')
        request.cookies.delete('session_refresh_token')
        return NextResponse.redirect(new URL('/', request.url));
    }

    if (!pathname.startsWith('/admin') && !pathname.startsWith('/user') && logedIn === '1' && userRole) {
        if (userRole === 'admin') {
            return NextResponse.redirect(new URL('/admin', request.url));
        } else if (userRole === 'user') {
            return NextResponse.redirect(new URL('/user', request.url));
        }
    }

    if (pathname.startsWith('/admin')) {
        if (userRole !== 'admin') {
            response.cookies.delete('Iloged')
            return NextResponse.redirect(new URL('/', request.url));
        }
    } else if (pathname.startsWith('/user')) {
        if (userRole !== 'user') {
            response.cookies.delete('Iloged')
            return NextResponse.redirect(new URL('/', request.url));
        }
    }

    response.cookies.set('session_access_token', token, {maxAge: 60 * 60});
    return response
}


async function checkUserAuth(accessToken: string | undefined) {
    const userId = await getUserId();
    if (userId) {

        const checkToken = await fetch(`${process.env.NEXT_PUBLIC_API_HOST}/api/auth/token/verify/`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${accessToken}`
            },
            body: JSON.stringify({"token": accessToken})
        });
        const tokens = await checkToken.json();

        if (Object.keys(tokens).length === 0) {
            const checkStaffRole = await fetch(`${process.env.NEXT_PUBLIC_API_HOST}/api/auth/check-auth/`, {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${accessToken}`
                }
            });

            const userData = await checkStaffRole.json();
            return userData?.user.role;
        }
    }
    return null;
}

async function getAccessToken(accessToken: string | undefined) {
    if (!accessToken) {
        const refreshToken = await getRefreshToken();
        try {
            const token = await fetch(`${process.env.NEXT_PUBLIC_API_HOST}/api/auth/token/refresh/`,
                {
                    method: 'POST',
                    headers: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({refresh: refreshToken})
                });

            const data = await token.json();
            if (data.access) {
                return data.access;
            }

        } catch (err) {
            console.error('mwrefreshError', err);
        }
    }
    return accessToken;
}
